package com.ruicar.afs.cloud.channel.grade.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruicar.afs.cloud.channel.grade.constant.Constants;
import com.ruicar.afs.cloud.channel.grade.entity.GradeModelElement;
import com.ruicar.afs.cloud.channel.grade.entity.GradeModelElementList;
import com.ruicar.afs.cloud.channel.grade.service.GradeModelElementListService;
import com.ruicar.afs.cloud.channel.grade.service.GradeModelElementService;
import com.ruicar.afs.cloud.channel.grade.utils.DicUtils;
import com.ruicar.afs.cloud.channel.grade.vo.GradeModelElementBean;
import com.ruicar.afs.cloud.channel.grade.vo.TreeNode;
import com.ruicar.afs.cloud.common.core.uid.AfsSequenceGenerator;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import com.ruicar.afs.cloud.components.datadicsync.DicHelper;
import com.ruicar.afs.cloud.components.datadicsync.dto.DicDataDto;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/grade/gradeModelElement")
@Api(value = "grade", description = "评级指标（指标分为一级大类和二级小类）controller")
public class GradeModelElementController {
    private static final Logger logger = LoggerFactory.getLogger(GradeModelElementController.class);

    @Autowired
    private GradeModelElementService gradeModelElementService;
    @Autowired
    private GradeModelElementListService gradeModelElementListService;
    @Autowired
    private AfsSequenceGenerator afsSequenceGenerator;

    @PostMapping("/getByModelCode")
    @ApiOperation(value = "查询评级模型指标（指标分为一级大类和二级小类），点击指标链展示页面用，查询单个指标")
    public IResponse<GradeModelElement> getByModelCode(@RequestBody GradeModelElement gradeModelElementCondition) throws Exception {
        if (gradeModelElementCondition == null) {
            return IResponse.fail("必传参数不能为空，请联系管理员！");
        }
        logger.info("getByModelCode方法输入参数：---->" + JSONObject.toJSONString(gradeModelElementCondition));
        if (StringUtils.isBlank(gradeModelElementCondition.getModelCode())) {
            return IResponse.fail("必传参数不能为空，请联系管理员！");
        }
        try {
            List<GradeModelElement> list = gradeModelElementService.list(Wrappers.<GradeModelElement>query().lambda()
                    .eq(GradeModelElement::getModelCode, gradeModelElementCondition.getModelCode())
                    .orderByAsc(GradeModelElement::getModelCode)
                    .orderByAsc(GradeModelElement::getElementNo)
                    .orderByAsc(GradeModelElement::getSeqno));
            if (CollectionUtils.isNotEmpty(list)) {
                List<GradeModelElementBean> gradeModelElementBeanList = new ArrayList();
                for (GradeModelElement gradeModelElement : list) {
                    GradeModelElementBean bean = new GradeModelElementBean();
                    try {
                        BeanUtils.copyProperties(gradeModelElement, bean);
                        //根据评分要素获取评分要素明细
                        List elementsList = gradeModelElementListService.list(Wrappers.<GradeModelElementList>query().lambda()
                                .eq(GradeModelElementList::getElementNo, bean.getElementNo())
                                .orderByAsc(GradeModelElementList::getId)
                                .orderByAsc(GradeModelElementList::getSeqno));
                        if (elementsList != null && elementsList.size() > 0) {
                            if (gradeModelElement.getElementEditType().equals("0")) { //评分要素是否有评分区间   0 表示
                                StringBuffer sb = new StringBuffer();
                                sb.append("<table border=1 cellspacing=0 cellpadding=0 width='100%'>");
                                for (int i = 0; i < elementsList.size(); i++) {
                                    GradeModelElementList gradeModelElementList = (GradeModelElementList) elementsList.get(i);
                                    String key = gradeModelElement.getElementEditSrc();
                                    String value = gradeModelElementList.getElementValue();
                                    Map<String, List<DicDataDto>> dataDicMap = DicHelper.getDicMaps(key);
                                    String datadicName = DicUtils.translate(value, dataDicMap);
                                    String score = gradeModelElementList.getScore();
                                    if (StringUtils.isEmpty(score)) {
                                        score = "";
                                    } else {
                                        score = score.replace("<", "&lt;").replace(">", "&gt;");
                                    }
                                    sb.append("<tr><td  width='50%'>").append(datadicName).append("</td><td  width='50%'>").append(score).append("</tr>");
                                }
                                sb.append("</table>");
                                bean.setElements(sb.toString());

                            } else if (gradeModelElement.getElementEditType().equals("1")) { //评分要素是否有评分区间
                                StringBuffer sb = new StringBuffer();
                                sb.append("<table border=1 cellspacing=0 cellpadding=0 width='100%'>");
                                for (int i = 0; i < elementsList.size(); i++) {
                                    GradeModelElementList gradeModelElementList = (GradeModelElementList) elementsList.get(i);
                                    String range = "";
                                    if (gradeModelElementList.getIsLowLimit()) {
                                        range += "[";
                                    } else {
                                        range += "(";
                                    }
                                    if (gradeModelElementList.getLowLimit() == null) {
                                        range += "-∞";
                                    } else {
                                        range += gradeModelElementList.getLowLimit();
                                    }
                                    range += ",&nbsp;";
                                    if (gradeModelElementList.getHighLimit() == null) {
                                        range += "+∞";
                                    } else {
                                        range += gradeModelElementList.getHighLimit();
                                    }
                                    if (gradeModelElementList.getIsHighLimit()) {
                                        range += "]";
                                    } else {
                                        range += ")";
                                    }
                                    String score = gradeModelElementList.getScore();
                                    if (StringUtils.isEmpty(score)) {
                                        score = "";
                                    } else {
                                        score = score.replace("<", "&lt;").replace(">", "&gt;");
                                    }
                                    sb.append("<tr><td  width='50%'>").append(range).append("</td><td  width='50%'>").append(score).append("</tr>");
                                }
                                sb.append("</table>");
                                bean.setElements(sb.toString());
                            } else if (gradeModelElement.getElementEditType().equals("2")) { //评分要素是否有评分公式
                                GradeModelElementList gradeModelElementList = (GradeModelElementList) elementsList.get(0);
                                String score = gradeModelElementList.getScore();
                                if (StringUtils.isEmpty(score)) {
                                    score = "";
                                } else {
                                    score = score.replace("<", "&lt;").replace(">", "&gt;");
                                }
                                bean.setElements(score);
                            }
                        }
                    } catch (Exception e) {
                        logger.error(e.getMessage(), e);
                    }
                    bean.setElementName(bean.getElementName());
                    gradeModelElementBeanList.add(bean);
                }
                List<TreeNode> returnList = new ArrayList();
                //为了展示树形结构，需要赋值hasChild属性
                for (int i = 0; i < gradeModelElementBeanList.size(); i++) {
                    GradeModelElementBean bean = (GradeModelElementBean) gradeModelElementBeanList.get(i);
                    String elementNo = bean.getElementNo().replaceAll("\\u0000", "");
                    String upElementNo = bean.getUpElementNo().replaceAll("\\u0000", "");
                    bean.setElementNo(elementNo);
                    bean.setUpElementNo(upElementNo);

                    TreeNode treeNode = new TreeNode();
                    treeNode.setHasChild(true);
                    treeNode.setId(elementNo);
                    treeNode.setPid(upElementNo);
                    treeNode.setAttributes(bean);
                    returnList.add(treeNode);
                }

                return IResponse.success("查询成功,无数据").setData(returnList);
            } else {
                return IResponse.success("查询成功,无数据").setData(new ArrayList());
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return IResponse.fail("查询失败，请联系管理员！");
        }
    }

    @PostMapping("/getByModelCodeAndElementNo")
    @ApiOperation(value = "查询评级模型指标（指标分为一级大类和二级小类），点击指标链展示页面用，查询单个指标")
    public IResponse<GradeModelElement> getByModelCodeAndElementNo(@RequestBody GradeModelElement gradeModelElement) throws Exception {
        if (gradeModelElement == null) {
            return IResponse.fail("必传参数不能为空，请联系管理员！");
        }
        logger.info("getByModelCodeAndElementNo方法输入参数：---->" + JSONObject.toJSONString(gradeModelElement));
        if (StringUtils.isBlank(gradeModelElement.getModelCode()) || StringUtils.isBlank(gradeModelElement.getElementNo())) {
            return IResponse.fail("必传参数不能为空，请联系管理员！");
        }
        try {
            List<GradeModelElement> list = gradeModelElementService.list(Wrappers.<GradeModelElement>query().lambda()
                    .eq(GradeModelElement::getModelCode, gradeModelElement.getModelCode())
                    .eq(GradeModelElement::getElementNo, gradeModelElement.getElementNo()));
            if (CollectionUtils.isNotEmpty(list)) {
                if (list.size() > 1) {
                    return IResponse.fail("数据异常，查到多条数据，请联系管理员！");
                } else if (list.size() == 1) {
                    return IResponse.success("查询成功").setData(list.get(0));
                }
                return IResponse.success("查询成功,无数据").setData("");
            } else {
                return IResponse.success("查询成功,无数据").setData("");
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return IResponse.fail("查询失败，请联系管理员！");
        }
    }

    @PostMapping("/getDataDicType")
    @ApiOperation(value = "获取数据字典大类，指标新增、修改页面用,个人评级字典固定数据，也可以配置到表")
    public IResponse<List<DicDataDto>> getDataDicType() throws Exception {
        List<DicDataDto> list = new ArrayList<DicDataDto>();
        DicDataDto dto = new DicDataDto();
        dto.setTitle("学历");
        dto.setValue("education");
        list.add(dto);
        dto = new DicDataDto();
        dto.setTitle("申请人从事行业\n");
        dto.setValue("industry");
        list.add(dto);
        dto = new DicDataDto();
        dto.setTitle("还款占比");
        dto.setValue("repaymentRate");
        list.add(dto);
        dto = new DicDataDto();
        dto.setTitle("信用卡透支额度合计");
        dto.setValue("creditOverdraftAmt");
        list.add(dto);
        dto = new DicDataDto();
        dto.setTitle("配偶从事的行业");
        dto.setValue("spouseIndustry");
        list.add(dto);
        dto.setTitle("申请人职称或职位");
        dto.setValue("applicantPosition");
        list.add(dto);
        dto = new DicDataDto();
        dto.setTitle("配偶职称或职位");
        dto.setValue("spousePosition");
        list.add(dto);
        dto = new DicDataDto();
        dto.setTitle("家庭状况");
        dto.setValue("familyStatus");
        list.add(dto);
        dto = new DicDataDto();
        dto.setTitle("现公司工作年限");
        dto.setValue("workYear");
        list.add(dto);
        dto = new DicDataDto();
        dto.setTitle("房屋性质");
        dto.setValue("houseProperty");
        list.add(dto);
        dto.setTitle("居住状态");
        dto.setValue("livingState");
        list.add(dto);
        dto = new DicDataDto();
        dto.setTitle("在当地城市居住年限");
        dto.setValue("livingYear");
        list.add(dto);
        dto = new DicDataDto();
        dto.setTitle("首付款");
        dto.setValue("firstPayment");
        list.add(dto);
        dto = new DicDataDto();
        dto.setTitle("还款期数");
        dto.setValue("repaymentPeriods");
        list.add(dto);
        dto = new DicDataDto();
        dto.setTitle("个人贷款额度");
        dto.setValue("loanLimit");
        list.add(dto);
        dto = new DicDataDto();
        dto.setTitle("还款记录");
        dto.setValue("repaymentRecord");
        list.add(dto);
        dto = new DicDataDto();
        dto.setTitle("合作情况");
        dto.setValue("cooperateStatus");
        list.add(dto);
        dto = new DicDataDto();
        dto.setTitle("担保方式");
        dto.setValue("guaranteeStyle");
        list.add(dto);
        dto = new DicDataDto();
        dto.setTitle("比率");
        dto.setValue("rate");
        list.add(dto);
        return IResponse.success("查询成功").setData(list);
    }

    @Transactional
    @PostMapping("/save")
    @ApiOperation(value = "保存评级模型指标（指标分为一级大类和二级小类，页面从不同的+按钮触发），新增单个指标")
    public IResponse<GradeModelElement> save(@RequestBody GradeModelElement gradeModelElement) throws Exception {
        if (gradeModelElement == null) {
            return IResponse.fail("参数不能为空，请联系管理员！");
        }
        logger.info("save方法输入参数：---->" + JSONObject.toJSONString(gradeModelElement));
        if (gradeModelElement.getModelCode() == null) {
            return IResponse.fail("参数不能为空，请联系管理员！");
        }
        try {
            //1、若为新增一级大类指标(指标类型是1并且上级指标编号是空)
            if (Constants.GRADE_MODEL_ELEMENT_TYPE_1.equals(gradeModelElement.getElementType()) && StringUtils.isBlank(gradeModelElement.getUpElementNo())) {
                gradeModelElement.setUpElementNo("");
            } else if (Constants.GRADE_MODEL_ELEMENT_TYPE_2.equals(gradeModelElement.getElementType()) && StringUtils.isNotBlank(gradeModelElement.getUpElementNo())) {
                //2、若为新增二级小类指标(指标类型是2并且上级指标编号不为空)
            } else {
                return IResponse.fail("输入参数异常，请联系管理员！");
            }
            //增加校验，一个模型中相同指标只能加一个
            List<GradeModelElement> existList = gradeModelElementService.list(Wrappers.<GradeModelElement>query().lambda()
                    .eq(GradeModelElement::getElementName, gradeModelElement.getElementName())
                    .eq(GradeModelElement::getModelCode, gradeModelElement.getModelCode()));
            if (CollectionUtils.isNotEmpty(existList)) {
                return IResponse.fail("一个模型中同一个指标不能添加多次！");
            }

            //判断序号是否存在，如果存在就是从指标中新增，原序号加1，如果不存在就是从因素中新增，序号最大值+1
            if (gradeModelElement.getSeqno() == null || "0".equals(String.valueOf(gradeModelElement.getSeqno())) || "".equals(String.valueOf(gradeModelElement.getSeqno()))) {
                List<GradeModelElement> list = gradeModelElementService.list(Wrappers.<GradeModelElement>query().lambda()
                        .eq(GradeModelElement::getUpElementNo, gradeModelElement.getUpElementNo()).orderByDesc(GradeModelElement::getSeqno));
                if (CollectionUtils.isNotEmpty(list)) {
                    GradeModelElement element = list.get(0);
                    gradeModelElement.setSeqno(element.getSeqno() + 1);
                } else {
                    gradeModelElement.setSeqno(1);
                }
                Long seqNo = afsSequenceGenerator.genNext(Constants.GRADE_MODEL_ELEMENT_INDEX_TYPE, Constants.GRADE_MODEL_ELEMENT_INDEX);
                String elementNo = gradeModelElement.getElementType() + DicUtils.intToString(seqNo.longValue(), 5);
                gradeModelElement.setElementNo(elementNo.replaceAll("\\u0000", ""));
                gradeModelElement.setElementCode(gradeModelElement.getElementName().replaceAll("\\u0000", ""));//指标名称由输入框改成下拉框，前台传code过来，前台展示的是中文

                gradeModelElementService.save(gradeModelElement);
                return IResponse.success("保存成功");
            } else {
                return IResponse.fail("保存失败，序列号seqno已存在，请联系管理员！");
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            //手动开启事务回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return IResponse.fail("保存失败，请联系管理员！");
        }
    }

    @Transactional
    @PostMapping("/edit")
    @ApiOperation(value = "修改评级模型指标（指标分为一级大类和二级小类）")
    public IResponse<GradeModelElement> edit(@RequestBody GradeModelElement gradeModelElement) throws Exception {
        if (gradeModelElement == null) {
            return IResponse.fail("必传参数不能为空，请联系管理员！");
        }
        logger.info("edit方法输入参数：---->" + JSONObject.toJSONString(gradeModelElement));
        if (StringUtils.isBlank(gradeModelElement.getModelCode()) || StringUtils.isBlank(gradeModelElement.getElementNo())) {
            return IResponse.fail("必传参数不能为空，请联系管理员！");
        }
        try {
            //本方法仅仅新增大类，默认设置为大类
            gradeModelElementService.update(Wrappers.<GradeModelElement>lambdaUpdate()
                    .eq(GradeModelElement::getElementNo, gradeModelElement.getElementNo())
                    .eq(GradeModelElement::getModelCode, gradeModelElement.getModelCode())
                    .set(GradeModelElement::getElementName, gradeModelElement.getElementName())
                    .set(GradeModelElement::getElementEditType, gradeModelElement.getElementEditType())
                    .set(GradeModelElement::getElementWeight, gradeModelElement.getElementWeight())
                    .set(GradeModelElement::getElementEditSrc, gradeModelElement.getElementEditSrc())
                    .set(GradeModelElement::getElementUse, gradeModelElement.getElementUse())
                    .set(GradeModelElement::getDscode, gradeModelElement.getDscode())
                    .set(GradeModelElement::getElementMin, gradeModelElement.getElementMin())
                    .set(GradeModelElement::getElementMax, gradeModelElement.getElementMax())
                    .set(GradeModelElement::getElementIgnore, gradeModelElement.getElementIgnore())
                    .set(GradeModelElement::getElementPlan, gradeModelElement.getElementPlan())
                    .set(GradeModelElement::getElementStand, gradeModelElement.getElementStand()));

            return IResponse.success("保存成功");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            //手动开启事务回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return IResponse.fail("保存失败，请联系管理员！");
        }
    }

    @Transactional
    @PostMapping("/delete")
    @ApiOperation(value = "删除评级模型指标（指标分为一级大类和二级小类）")
    public IResponse<GradeModelElement> delete(@RequestBody GradeModelElement gradeModelElement) throws Exception {
        if (gradeModelElement == null) {
            return IResponse.fail("必传参数不能为空，请联系管理员！");
        }
        logger.info("delete方法输入参数：---->" + JSONObject.toJSONString(gradeModelElement));
        if (StringUtils.isBlank(gradeModelElement.getModelCode()) || StringUtils.isBlank(gradeModelElement.getElementNo())) {
            return IResponse.fail("必传参数不能为空，请联系管理员！");
        }
        try {
            gradeModelElementService.remove(Wrappers.<GradeModelElement>query().lambda().eq(GradeModelElement::getModelCode, gradeModelElement.getModelCode())
                    .eq(GradeModelElement::getElementNo, gradeModelElement.getElementNo()));
            return IResponse.success("删除成功");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            //手动开启事务回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return IResponse.fail("删除失败，请联系管理员！");
        }
    }

}
